package algo3.algothief.modelo;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import algo3.algothief.excepcion.CasoAunEnCursoException;
import algo3.algothief.excepcion.CasoNoIniciadoException;
import algo3.algothief.excepcion.LadronNoRoboAunException;
import algo3.algothief.excepcion.LugarInvalidoParaVisitarDesdeEPaislActualException;
import algo3.algothief.excepcion.NombreDelJugadorNoDefinidoException;
import algo3.algothief.excepcion.PaisInvalidoParaViajarDesdeElActualException;


public class Juego {
	
	private String nombreDelJugador;
	
	private Tiempo tiempoActual;
	
	private Mundo mundo;
	
	private CuartelGeneral cuartelGeneral;
	private Policia jugador;
	private Caso casoActual;
	
	private EstadoDelJuego estado;
	
	
	private static String direccionDeLasDescripciones = "descripciones.xml"; 
	private static String direccionDeLosPaises = "paises.xml";
	
	private static String textoDescriptivoParaGuardarYCargarPartidas = "Partida-Algo-Thief-";
	
//-------------------------------------------------------------------------------------
	
	public Juego() throws ParserConfigurationException, SAXException, IOException {
		this.nombreDelJugador = null;
		
		this.mundo = this.inicializarMundo(); 
		
		this.cuartelGeneral = this.inicializarCuartelGeneral();
		this.jugador = this.inicializarPolicia();
	}
	
	private Juego(String nombreNuevo, Tiempo tiempoNuevo, Mundo mundoNuevo, CuartelGeneral cuartelNuevo, Policia jugadorNuevo, Caso casoNuevo) {
		this.nombreDelJugador = nombreNuevo;
		
		this.tiempoActual = tiempoNuevo;
		
		this.mundo = mundoNuevo;
		
		this.cuartelGeneral = cuartelNuevo;
		this.jugador = jugadorNuevo;
		this.casoActual = casoNuevo;
	}
	
//-------------------------------------------------------------------------------------

	public void guardarLaPartida() throws CasoNoIniciadoException, ParserConfigurationException, TransformerException, NombreDelJugadorNoDefinidoException {
		// El nombre del archivo sera por una parte un texto descriptivo, y por
		// otra parte, el nombre del jugador que jugo en esta instancia de Juego.
		String nombreDelArchivo = textoDescriptivoParaGuardarYCargarPartidas + nombreDelJugador + ".xml";
		this.eliminarPartidaAnterior(nombreDelArchivo);
		
		// Se crean los elementos para poder serializar el juego.
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.newDocument();
		
		// Se serializa el juego.
		Element juegoSerializado = this.serializar(doc);
		
		// Creacion del archivo contenedor de los datos del juego.
		doc.appendChild(juegoSerializado);
				
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		
		DOMSource source = new DOMSource(doc);
		File archivoDestino = new File(nombreDelArchivo);
		StreamResult result = new StreamResult(archivoDestino);
			
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4");
		transformer.transform(source, result);
	}
	
	public boolean cargarUnaPartida(String nombreDelJugador) throws ParserConfigurationException, SAXException, IOException {
		// El nombre del archivo sera por una parte un texto descriptivo, y por
		// otra parte, el nombre del jugador que jugo en esta instancia de Juego.
		String direccionDelArchivo = textoDescriptivoParaGuardarYCargarPartidas + nombreDelJugador + ".xml";

		File archivo = new File(direccionDelArchivo);
		if (!archivo.exists()) return false;
		
		Document doc = Juego.cargarDocumentoNormalizado(archivo);
		Juego juegoCargado = Juego.hidratar(doc);
		
		this.actualizarJuego(juegoCargado);
		return true;
	}
	
//-------------------------------------------------------------------------------------

	public Element serializar(Document doc) throws CasoNoIniciadoException, NombreDelJugadorNoDefinidoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		if (nombreDelJugador == null)
			throw new NombreDelJugadorNoDefinidoException();
			
		Element elementoJuego = doc.createElement("Juego");
		elementoJuego.setAttribute("nombreDelJugador", nombreDelJugador);
		
		Element elementoTiempo = tiempoActual.serializar(doc);
		Element elementoMundo = mundo.serializar(doc);
		Element elementoCuartel = cuartelGeneral.serializar(doc);
		Element elementoJugador = jugador.serializar(doc);
		Element elementoCaso = casoActual.serializar(doc);
		Element elementoEstado = estado.serializar(doc);
		
		elementoJuego.appendChild(elementoTiempo);
		elementoJuego.appendChild(elementoMundo);
		elementoJuego.appendChild(elementoCuartel);
		elementoJuego.appendChild(elementoJugador);
		elementoJuego.appendChild(elementoCaso);
		elementoJuego.appendChild(elementoEstado);
					
		return elementoJuego;
	}
		
	public static Juego hidratar(Document doc) throws ParserConfigurationException, SAXException, IOException {
		Element elementoJuego = (Element)doc.getElementsByTagName("Juego").item(0);
		String nombreDelJugador = elementoJuego.getAttribute("nombreDelJugador");
		
		Tiempo tiempoNuevo = Tiempo.hidratar(doc);
		Mundo mundoNuevo = Mundo.hidratar(doc);
		CuartelGeneral cuartelNuevo = CuartelGeneral.hidratar(doc);
		
		ArrayList<Pais> paisesDelMundoNuevo = mundoNuevo.verPaisesDelMundo();
		
		Policia jugadorNuevo = Policia.hidratar(doc, paisesDelMundoNuevo);
		Caso casoNuevo = Caso.hidratar(doc, paisesDelMundoNuevo);
		
		Juego juegoNuevo = new Juego(nombreDelJugador,tiempoNuevo,mundoNuevo,cuartelNuevo,jugadorNuevo,casoNuevo);
		
		EstadoDelJuego estadoNuevo = EstadoDelJuego.hidratar(doc, juegoNuevo);
		juegoNuevo.definirEstadoDelJuegoActual(estadoNuevo);
		
		return juegoNuevo;
	}
	
//-------------------------------------------------------------------------------------
	
	private void actualizarJuego(Juego juegoCargado) {
		this.nombreDelJugador = juegoCargado.verElNombreDelJugador();
		this.tiempoActual = juegoCargado.verElTiempo();
		this.mundo = juegoCargado.verElMundo();
		this.cuartelGeneral = juegoCargado.verElCuartelGeneral();
		this.jugador = juegoCargado.verAlJugador();
		this.casoActual = juegoCargado.verElCasoActual();
		this.estado = juegoCargado.verElEstadoDelJuego();
		
		estado.actualizarJuego(this);
	}
	
	
	
	private void eliminarPartidaAnterior(String nombreDelArchivo) {
		File archivo = new File(nombreDelArchivo);
		if (archivo.exists()) 
			archivo.delete();
	}
	
	
	
	private void definirEstadoDelJuegoActual(EstadoDelJuego estadoNuevo) {
		this.estado = estadoNuevo;
	}
	
	
	
	private static Document cargarDocumentoNormalizado(File archivo) throws ParserConfigurationException, SAXException, IOException {
		// Se traduce el archivo a algo manejable para el programa.
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(archivo);
		doc.getDocumentElement().normalize();
		
		return doc;
	}
	
	
	
	private Mundo inicializarMundo() throws ParserConfigurationException, SAXException, IOException {
		Mundo mundoNuevo = new Mundo(direccionDeLosPaises);
		
		return mundoNuevo;
	}
	
	
	private CuartelGeneral inicializarCuartelGeneral() throws ParserConfigurationException, SAXException, IOException {
		CuartelGeneral cuartelGeneral = new CuartelGeneral(direccionDeLasDescripciones);
		
		return cuartelGeneral;
	}
	
	
	private Policia inicializarPolicia() {
		RangoPolicia rangoInicial = new RangoNovato();
		
		Policia policia = new Policia(rangoInicial);
		
		return policia;
	}
	
	private Tiempo inicializarTiempo() {
		Tiempo tiempo = new Tiempo("Lunes", 7);
		tiempo.definirDiaYHoraLimite("Domingo", 17);
		
		return tiempo;
	}
	

	
	private Pais elegirPaisAlAzar() {
		ArrayList<Pais> paises = mundo.verPaisesDelMundo();
		int cantidadDePaises = paises.size();
		
		Random generadorAleatorio = new Random();
		int indiceDeUnPaisAlAzar = generadorAleatorio.nextInt(cantidadDePaises); 
		
		Pais paisAlAzar = paises.get(indiceDeUnPaisAlAzar);
		
		return paisAlAzar;
	}
	
	private Ladron elegirLadronAlAzar() {
		BaseDeDatosDeLadrones ladrones = cuartelGeneral.verLaBaseDeDatosDeLadrones();
		int cantidadDeLadrones = ladrones.verLaCantidadDeLadrones();
		
		Random generadorAleatorio = new Random();
		int numeroAlAzar = generadorAleatorio.nextInt(cantidadDeLadrones); 
		
		DescripcionDeLadron descripcionDeUnLadronAlAzar = ladrones.obtenerLaDescripcionDeUnLadron(numeroAlAzar);
		Ladron ladronAlAzar = new Ladron(descripcionDeUnLadronAlAzar);
		
		return ladronAlAzar;
	}
	
	
	private void avanzarElTiempoACausaDeInteractuarConElLugar(LugarDePais lugar) {
		int horasTranscurridasPorEntrarAlLugar = lugar.verElTiempoTranscurridoPorEntrarAlLugar();
		tiempoActual.avanzarTiempo(horasTranscurridasPorEntrarAlLugar);
		
		int horasTranscurridasPorObtenerLaPista = lugar.verElTiempoTranscurridoPorObtenerLaPista();
		tiempoActual.avanzarTiempo(horasTranscurridasPorObtenerLaPista);
	}
	
	
	
	private Tiempo verElTiempo() {
		return this.tiempoActual;
	}
	
	private Mundo verElMundo() {
		return this.mundo;
	}
	
	private CuartelGeneral verElCuartelGeneral() {
		return this.cuartelGeneral;
	}
	
	private Policia verAlJugador() {
		return this.jugador;
	}
	
	private Caso verElCasoActual() {
		return this.casoActual;
	}
	
	private EstadoDelJuego verElEstadoDelJuego() {
		return this.estado;
	}
	
	
	private int buscarIndiceEnPaisesDelPais(ArrayList<Pais> paises, Pais pais) {
		int indiceDelPais = -1;
		int cantidadDePaises = paises.size();
		
		for (int i = 0; ( (indiceDelPais == -1) && (i < cantidadDePaises) ); i++) {
			if (pais == paises.get(i)) 
				indiceDelPais = i;
		}
		
		return indiceDelPais;
	}
	
	private int buscarIndiceEnLugaresDelLugar(HashMap<String, LugarDePais> lugares, LugarDePais lugar) {
		int indiceDelLugar = -1;
		
		int i = 0;
		for (Entry<String, LugarDePais> lugarActual : lugares.entrySet()) {	
			LugarDePais posibleLugar = lugarActual.getValue();
			
			if (lugar == posibleLugar) 
				indiceDelLugar = i;
			i++;
		}
		
		return indiceDelLugar;
	}
	
//-------------------------------------------------------------------------------------
	
	public void definirNombreDelJugador(String nombre) {
		this.nombreDelJugador = nombre;
	}
	
	public String verElNombreDelJugador() {
		return this.nombreDelJugador;
	}
	
	public String obtenerElRangoDelJugador() {
		return jugador.obtenerElRango();
	}
	
	public int verLaCantidadDeArrestosActual() {
		return jugador.verLaCantidadDeArrestosActual();
	}
	
	public int verArrestosFaltantesParaLaProximaPromocion() {
		return jugador.verCuantosArrestosFaltanParaLaProximaPromocion();
	}
	
	
	
	public void iniciarNuevoCaso() throws CasoAunEnCursoException, ParserConfigurationException, SAXException, IOException {
		if (casoActual != null)
			throw new CasoAunEnCursoException();
			
		this.tiempoActual = this.inicializarTiempo();
		
		jugador.modificarDescripcionDelSospechoso(new HashMap<String, String>());
		
		ObjetoRobado objetoRobado = jugador.definirObjetoQueSeRobaraSegunElRango();
		
		Pais pais = this.elegirPaisAlAzar();
		objetoRobado.definirPaisDeOrigen(pais);
		objetoRobado.definirNombreDelObjeto(pais);
		
		try {
			Ladron ladron = this.elegirLadronAlAzar();
			ladron.robar(objetoRobado, mundo);
		
			this.casoActual = new Caso(ladron);
			jugador.asignarUnCaso(casoActual);
		}
		catch (LadronNoRoboAunException excepcion) {
			// Nunca se llega a esta situacion porque
			// se roba inmediatamente antes de crear
			// el nuevo caso.
		}
		
		this.estado = new JuegoEnCurso(this);
	}
	
	public void finalizarCasoActual() throws CasoNoIniciadoException, ParserConfigurationException, SAXException, IOException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		casoActual.finalizarCaso();
		
		if (estado.verMensajeInformativoDelEstado() == "Atrapaste al ladron.")
			jugador.incrementarCantidadDeArrestos(1);
		
		this.tiempoActual = null;
		this.casoActual = null;
	}

	
	
	public Object[] verFechaYHora() throws CasoNoIniciadoException {
		if (tiempoActual == null)
			throw new CasoNoIniciadoException();

		return tiempoActual.verFechaYHora();
	}
	
	public Object[] verFechaYHoraLimites() throws CasoNoIniciadoException {
		if (tiempoActual == null)
			throw new CasoNoIniciadoException();
		
		return tiempoActual.verFechaYHoraLimites();
	}
	
	public int[] verTiempoRestante() throws CasoNoIniciadoException {
		if (tiempoActual == null)
			throw new CasoNoIniciadoException();

		return tiempoActual.verTiempoRestante();
	}
	
	
	
	public Pais verElPaisActual() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();

		return jugador.verPaisDondeEsta();
	}
	
	public String verElNombreDelObjetoRobado() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		Ladron ladron = casoActual.verLadron();
		return ladron.verElNombreDelObjetoRobado();
	}
	
	public String verElNombreDelPaisActual() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return jugador.verPaisDondeEsta().verNombreDeLaCapital();
	}
	
	public String verLaDescripcionDelPaisActual() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return jugador.verPaisDondeEsta().verDescripcionSobreElPais();
	}
	
	public String verElNombreDelLadronActual() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();

		return casoActual.verNombreDelLadron();
	}
	
	
	
	public ArrayList<Pais> obtenerRutaDeEscapeDelLadron() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return casoActual.verRutaTomadaPorElLadron();
	}
	
	public String verPistaInicialSobreElLadron() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		Ladron ladron = casoActual.verLadron();
		DescripcionDeLadron descripcionDelLadron = ladron.verDescripcion();
		
		return descripcionDelLadron.verCaracteristica("Sexo");
	}
	
	
	
	public ArrayList<Pais> verHaciaQuePaisesSePuedeViajar() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return this.estado.verHaciaQuePaisesSePuedeViajar();
	}
	
	public ArrayList<Pais> verHaciaQuePaisesSePuedeViajar(JuegoEnCurso juegoEnCurso) {
		Pais paisActual = jugador.verPaisDondeEsta();
		
		ArrayList<Pais> posiblesPaisesParaViajar = mundo.verLosPosiblesPaisesALosQueSePuedeViajar(paisActual);
	
		return posiblesPaisesParaViajar;
	}
	
	public ArrayList<Pais> verHaciaQuePaisesSePuedeViajar(JuegoTerminado juegoTerminado) {
		return null;
	}
	
	
	public boolean viajarA(Pais pais) throws CasoNoIniciadoException, PaisInvalidoParaViajarDesdeElActualException, ParserConfigurationException, SAXException, IOException{
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		Pais paisActual = jugador.verPaisDondeEsta();
		ArrayList<Pais> posiblesPaisesParaViajar = mundo.verLosPosiblesPaisesALosQueSePuedeViajar(paisActual);
		
		int indiceDelPais = this.buscarIndiceEnPaisesDelPais(posiblesPaisesParaViajar, pais);
		if (indiceDelPais == -1)
			throw new PaisInvalidoParaViajarDesdeElActualException();
		
		return this.estado.viajarA(pais);
	}
	
	public boolean viajarA(Pais pais, JuegoEnCurso juegoEnCurso) throws ParserConfigurationException, SAXException, IOException {
		int horasDeViaje = casoActual.viajarAUnPais(jugador, pais);
		tiempoActual.avanzarTiempo(horasDeViaje);
		
		this.estado = estado.comprobarPosibleCambioDeEstadoACausaDelTiempo(tiempoActual);
		
		if ( casoActual.policiaEstaEnUltimoPais() ) 
			this.estado = estado.modificarEstadoACausaDeLlegarAlUltimoPais();
		
		return true;
	}
	
	public boolean viajarA(Pais pais, SeLlegoAlUltimoPais seLlegoAlUltimoPais) throws ParserConfigurationException, SAXException, IOException {
		int horasDeViaje = casoActual.viajarAUnPais(jugador, pais);
		tiempoActual.avanzarTiempo(horasDeViaje);
		
		this.estado = estado.comprobarPosibleCambioDeEstadoACausaDelTiempo(tiempoActual);
		
		this.estado = estado.modificarEstadoACausaDeSalirDelUltimoPais();
		
		return true;
	}
	
	public boolean viajarA(Pais pais, JuegoTerminado juegoTerminado) throws ParserConfigurationException, SAXException, IOException {
		return false;
	}
	
	
	
	public boolean seLlegoAlUltimoPaisDelCaso() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return casoActual.policiaEstaEnUltimoPais();
	}
	
	
	
	public HashMap<String, LugarDePais> verQueLugaresSePuedenVisitar() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return this.estado.verQueLugaresSePuedenVisitar();
	}
	
	public HashMap<String, LugarDePais> verQueLugaresSePuedenVisitar(JuegoEnCurso juegoEnCurso) {
		Pais paisActual = jugador.verPaisDondeEsta();
		
		HashMap<String, LugarDePais> posiblesLugaresParaVisitar = paisActual.verLosPosiblesLugaresQueSePuedenVisitar();
	
		return posiblesLugaresParaVisitar;
	}
	
	public HashMap<String, LugarDePais> verQueLugaresSePuedenVisitar(JuegoTerminado juegoTerminado) {
		return null;
	}
	
	
	public String visitar(LugarDePais lugar) throws CasoNoIniciadoException, LugarInvalidoParaVisitarDesdeEPaislActualException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		Pais paisActual = jugador.verPaisDondeEsta();
		HashMap<String, LugarDePais> posiblesLugaresParaVisitar = paisActual.verLosPosiblesLugaresQueSePuedenVisitar();
		
		int indiceDelLugar = this.buscarIndiceEnLugaresDelLugar(posiblesLugaresParaVisitar, lugar);
		if (indiceDelLugar == -1)
			throw new LugarInvalidoParaVisitarDesdeEPaislActualException();
		
		return this.estado.visitar(lugar);
	}
	
	public String visitar(LugarDePais lugar, JuegoEnCurso juegoEnCurso) {
		String pistaParaElJugador = casoActual.visitarUnLugar(jugador, lugar);
		this.avanzarElTiempoACausaDeInteractuarConElLugar(lugar);
		
		this.estado = estado.comprobarPosibleCambioDeEstadoAlVisitarUnLugar(casoActual, cuartelGeneral, lugar);
		this.estado = estado.comprobarPosibleCambioDeEstadoACausaDelTiempo(tiempoActual);
		
		return pistaParaElJugador;
	}
	
	public String visitar(LugarDePais lugar, JuegoTerminado juegoTerminado) {
		return null;
	}
	
	
	
	public HashMap<String, ArrayList<String>> verLasPosiblesOpcionesParaModificarLaDescripcionDelSospechoso() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return jugador.verOpcionesPosiblesParaLaDescripcionDelSospechoso();
	}
	
	public HashMap<String, String> verLasCaracteristicasDelSospechoso() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		DescripcionDeLadron descripcionDelSospechoso = jugador.verLaDescripcionDelSospechosoHechaPorElPolicia();
		
		HashMap<String,String> caracteristicas = new HashMap<String, String>();
		
		caracteristicas.put("Sexo", descripcionDelSospechoso.verCaracteristica("Sexo"));
		caracteristicas.put("Hobby", descripcionDelSospechoso.verCaracteristica("Hobby"));
		caracteristicas.put("Cabello", descripcionDelSospechoso.verCaracteristica("Cabello"));
		caracteristicas.put("Senia", descripcionDelSospechoso.verCaracteristica("Senia"));
		caracteristicas.put("Vehiculo", descripcionDelSospechoso.verCaracteristica("Vehiculo"));
		
		return caracteristicas;
	}
	
	
	public boolean modificarLaDescripcionDelSospechoso(HashMap<String,String> caracteristicasElegidasPorElJugador) throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return estado.modificarLaDescripcionDelSospechoso(caracteristicasElegidasPorElJugador);
	}
	
	public boolean modificarLaDescripcionDelSospechoso(HashMap<String,String> caracteristicasElegidasPorElJugador, JuegoEnCurso juegoEnCurso) {
		jugador.modificarDescripcionDelSospechoso(caracteristicasElegidasPorElJugador);
		return true;
	}
	
	public boolean modificarLaDescripcionDelSospechoso(HashMap<String,String> caracteristicasElegidasPorElJugador, JuegoTerminado juegoTerminado) {
		return false;
	}
	
	
	
	public ArrayList<DescripcionDeLadron> verSospechososQueConcuerdanConLaDescripcionHechaPorElJugador() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		BaseDeDatosDeLadrones baseDeDatos = cuartelGeneral.verLaBaseDeDatosDeLadrones();
		DescripcionDeLadron descripcionDelSospechoso = jugador.verLaDescripcionDelSospechosoHechaPorElPolicia();
		
		return baseDeDatos.verSospechososQueConcuerdanConLaDescripcion(descripcionDelSospechoso);
	}
	
	public boolean emitirOrdenDeArresto() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return this.estado.emitirOrdenDeArresto();
	}
	
	public boolean emitirOrdenDeArresto(JuegoEnCurso juegoEnCurso) {
		int horasTranscurridasPorEmitirLaOrden = jugador.emitirOrdenDeArresto(cuartelGeneral);
		tiempoActual.avanzarTiempo(horasTranscurridasPorEmitirLaOrden);
		
		this.estado = estado.comprobarPosibleCambioDeEstadoACausaDelTiempo(tiempoActual);
		this.estado = estado.modificarEstadoACausaDeEmitirOrdenDeArresto();
		
		return true;
	}
	

	public boolean emitirOrdenDeArresto(JuegoTerminado juegoTerminado) {
		return false;
	}
	
	
	
	public boolean sePuedeSeguirJugando() throws CasoNoIniciadoException {
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return estado.verSiSePuedeSeguirJugando();
	}
	
	public String verDescripcionDelEstadoDelJuego() throws CasoNoIniciadoException{
		if (casoActual == null)
			throw new CasoNoIniciadoException();
		
		return estado.verMensajeInformativoDelEstado();
	}
}